using System;
using System.Collections.Generic;
using System.Text;
using Dracham.Classes;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Dracham.TileManagement.CharacterManagement.Animation;
using Dracham.Network;
using Microsoft.Xna.Framework.Input;
using Dracham.GUI.Controls;

namespace Dracham.TileManagement.CharacterManagement
{
    public class MobileObject
    {
        private String mobId;
        private Model model;
        private Position position;
        private Position lastPosition;
        private Position newPosition;
        private String direction = "Up";
        private Boolean isMarked = false;

        private Boolean isDead = false;

        public Boolean IsDead
        {
            get { return isDead; }
            set { isDead = value; }
        }

        private Double timeSinceLastMove = 0;

        #region properties

        public String MobId
        {
            get { return this.mobId; }
        }

        public Boolean IsMarked
        {
            get { return this.isMarked; }
        }

        public Model Model
        {
            get { return this.model; }
        }

        public Position Position
        {
            get { return this.position; }
        }

        public Position LastPosition
        {
            get { return this.lastPosition; }
        }

        #endregion

        public MobileObject(String mobId, String modelId, Position fromPosition, Position startPos)
        {
            this.mobId = mobId;
            this.model = ModelFactory.GetModelById(modelId);
            this.position = startPos;
            this.lastPosition = fromPosition;
            this.newPosition = startPos;
        }

        public void UpdatePosition(Int32 x, Int32 y, Int32 lx, Int32 ly)
        {
            this.lastPosition = new Position(lx, ly, this.position.Zone);
            this.position = new Position(lx, ly, this.position.Zone);
            this.timeSinceLastMove = 0;

            this.newPosition = new Position(x, y, this.position.Zone);

            #region get direction image

            if (this.newPosition.MapX < this.position.MapX)
            {
                direction = "Left";
            }
            else if (this.newPosition.MapX > this.position.MapX)
            {
                direction = "Right";
            }
            else if (this.newPosition.MapY < this.position.MapY)
            {
                direction = "Up";
            }
            else if (this.newPosition.MapY > this.position.MapY)
            {
                direction = "Down";
            }

            #endregion
        }

        public void Update(GameTime gameTime, Int32 renderPosX, Int32 renderPosY)
        {
            if (IsDead) return;
            MouseState mouseState = Mouse.GetState();

            if (mouseState.LeftButton == ButtonState.Pressed ||mouseState.RightButton == ButtonState.Pressed)
            {
                if (
                    mouseState.X > renderPosX &&
                    mouseState.Y > renderPosY &&
                    mouseState.X < (renderPosX + Dracham.TileWidth) &&
                    mouseState.Y < (renderPosY + Dracham.TileHeight) &&
                    mouseState.X > Dracham.GuiX
                    )
                {
                    this.isMarked = true;

                    if (mouseState.RightButton == ButtonState.Pressed)
                    {
                        Dracham.Player.Attack(this);
                    }
                }
                else
                {
                    this.isMarked = false;
                }
            }
        }

        public void Render(SpriteBatch spriteBatch, GameTime gameTime, Int32 posx, Int32 posy, Int32 tileX, Int32 tileY, Player player)
        {
            if (IsDead) return;

            Boolean isMoving = false;
            if (newPosition.MapX != position.MapX)
            {
                //
                // update time
                this.timeSinceLastMove += gameTime.ElapsedGameTime.Milliseconds;

                isMoving = true;
                Int32 x = (Int32)(Dracham.TileWidth * ((float)timeSinceLastMove / this.model.MoveSpeed));

                this.position.TileX = (newPosition.MapX > position.MapX) ? x : 0 - x;
                if (this.timeSinceLastMove > this.model.MoveSpeed)
                {
                    this.position.TileX = 0;
                    this.position.MapX = this.newPosition.MapX;
                    this.timeSinceLastMove = 0;
                }
            }
            if (newPosition.MapY != position.MapY)
            {
                //
                // update time
                this.timeSinceLastMove += gameTime.ElapsedGameTime.Milliseconds;

                isMoving = true;
                Int32 y = (Int32)(Dracham.TileHeight * ((float)timeSinceLastMove / this.model.MoveSpeed));

                this.position.TileY = (newPosition.MapY > position.MapY) ? y : 0 - y;
                if (this.timeSinceLastMove > this.model.MoveSpeed)
                {
                    this.position.TileY = 0;
                    this.position.MapY = this.newPosition.MapY;
                    this.timeSinceLastMove = 0;
                }
            }

            Int32 tilePosX = (6 + (this.position.MapX - posx));
            Int32 tilePosY = (6 + (this.position.MapY - posy));

            Walk w = model.GetWalkByDirection(direction);
            if (isMoving)
            {
                w.Update(gameTime);
            }

            #region draw 

            //Dracham.DrachamNetwork.Invoke(global::Dracham.Network.RequestType.Unknown,
            //                new NetworkParameter(String.Format("tpy: {0}, ty: {1}, pty: {2}", tilePosY, tileY, this.position.TileY), 100));

            Int32 renderPosX = ((tilePosX * Dracham.TileWidth) + tileX + (Dracham.TileWidth * 8)) + this.position.TileX;
            Int32 renderPosY = (tilePosY * Dracham.TileHeight) + tileY + this.position.TileY;

            Update(gameTime, renderPosX, renderPosY);

            spriteBatch.Draw(
                           model.Texture,
                           new Rectangle(
                                renderPosX,
                                renderPosY,
                                Dracham.TileWidth,
                                Dracham.TileHeight),
                           new Microsoft.Xna.Framework.Rectangle(
                                w.Image.X * Dracham.TileWidth, // X
                                w.Image.Y * Dracham.TileHeight, // Y
                                Dracham.TileWidth,
                                Dracham.TileHeight),
                            Color.White);

            if (isMarked)
            {
                spriteBatch.Draw(Dracham.ContentManager.Load<Texture2D>("mark"),
                    new Rectangle(renderPosX - 1, renderPosY - 1, 33, 33), Color.White);
            }

            #endregion
        }
    }
}
